<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h3 v-html="msg" @click="change"></h3>
        <input type="text" v-model="msg">
        <p v-html="msg" v-on:click="change"></p>
    </div>
    <script>
        class Watcher {
          constructor () {
            this.guanjia = {
              // 收集 []
            }
          }
        }
        Watcher.prototype.$on = function(eventName, listener){
            if(this.guanjia[eventName]) {
                this.guanjia[eventName].push(listener)
            } else {
                this.guanjia[eventName] = [listener]
            }
        }
        // 发布事件，通知相关的观察者去执行
        Watcher.prototype.$emit = function(eventName) {
            if (this.guanjia[eventName]){
                this.guanjia[eventName].forEach(fn => fn())
            }
        }
        
        const watcher = new Watcher()

        function Vue (options) {
          const { el, data, methods } = options
          for (let key in data) {
            Object.defineProperty(this, key, {
              get () {
                return data[key]
              },
              set (newVal) {
                data[key] = newVal
                watcher.$emit(key)
              }
            })
          }

          for (let key in methods) {
              Object.defineProperty(this, key, {
                  get () {
                    console.log('getter')
                    return methods[key]
                  },
                  set (newFn) {
                    return
                  }
              }) 
          }

          const app = document.querySelector(el);
          [...app.children].map(node => {
            if (node.hasAttribute('v-html')) {
              let key = node.getAttribute('v-html')
              node.innerHTML = this[key]
              watcher.$on(key, () => {
                node.innerHTML = this[key]
              })
            }
            if (node.hasAttribute('v-model')) {
              let key = node.getAttribute('v-model')
              node.value = this[key]
              watcher.$on(key, () => {
                node.value = this[key]
              })
              node.addEventListener('input', () => {
                this[key] = node.value
              })
            }
            if (node.hasAttribute('@click') || node.hasAttribute('v-on:click')) {
              let key = node.getAttribute('@click') || node.getAttribute('v-on:click')
              node.addEventListener('click', this[key])
            }
          })

        }


        const vm = new Vue({
          el: '#app',
          data: {
            msg: 5000
          },
          methods: {
            change () {
              console.log('change')
            }
          }, 
          computed: {
            cUserName () {
              return 'berlin'
            }
          }
        })

        console.log(vm)

    </script>
</body>
</html>